package com.camel.chart.utils;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.io.IoUtil;
import com.camel.chart.utils.entity.ApplicationConfig;
import com.camel.chart.utils.entity.NetDevice;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Vector;
import java.util.concurrent.ConcurrentHashMap;

public class IPUtils {


    public static ConcurrentHashMap<String, String> pingMap = new ConcurrentHashMap<String, String>();


    private volatile static IPUtils instance;

    private IPUtils() {
    }

    public static synchronized IPUtils getInstance() {
        if (instance == null) {
            synchronized (IPUtils.class) {
                if (instance == null) {
                    instance = new IPUtils();
                }
            }
        }
        return instance;
    }

    /**
     * 获取所有IP地址
     *
     * @param hostAddress
     * @throws Exception
     */
    public void gainAllIp(String hostAddress) throws Exception {
        // 获得IP地址中最后一个点的位置
        int pos = hostAddress.lastIndexOf(".");
        // 对本机的IP进行截取，获得网段
        String wd = hostAddress.substring(0, pos + 1);
        ArrayList<PingIpThread> pingIpThreads = new ArrayList<>();
        for (int i = 1; i <= 255; i++) {
            String ip = wd + i;
            // 创建线程对象
            IPUtils.PingIpThread thread = new PingIpThread(ip);
            pingIpThreads.add(thread);
        }
        for (PingIpThread pingIpThread : pingIpThreads) {
            pingIpThread.start();
        }
        for (PingIpThread pingIpThread : pingIpThreads) {
            pingIpThread.join();
        }
    }


    /**
     * 判断给定IP是否为内网IP的线程对象
     */
    static class PingIpThread extends Thread {

        /**
         * 表示IP地址的成员变量
         */
        public String ip;

        /**
         * 参数为需要判断的IP地址
         *
         * @param ip
         */
        public PingIpThread(String ip) {
            this.ip = ip;
        }

        public void run() {
            try {
                // 获得所ping的IP进程，-w 280是等待每次回复的超时时间，-n 1是要发送的回显请求数
                System.out.println("尝试ping IP:" + ip);
                Process process = Runtime.getRuntime().exec(
                        "ping " + ip + " -w 280 -n 1");
                InputStream is = process.getInputStream();// 获得进程的输入流对象
                InputStreamReader isr = new InputStreamReader(is);// 创建InputStreamReader对象
                BufferedReader in = new BufferedReader(isr);// 创建缓冲字符流对象
                String line = IoUtil.read(is, "GBK");//CMD获取的值是GBK格式的
                //String line = in.readLine();// 读取信息
                if (line != null && !line.isEmpty()) {
                    if (line.indexOf("来自") > 0 || line.indexOf("Reply from") > 0) {// 判断是ping通过的IP地址
                        if (CollectionUtil.isEmpty(ApplicationConfig.getInstance().getDevices())) {
                            ApplicationConfig.getInstance().setDevices(new Vector<>());
                        }
                        ApplicationConfig.getInstance().getDevices().add(new NetDevice(ip));// 向集合中添加IP
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public static byte[] getInetAddress() {
        try {
            return ApplicationConfig.getInstance().getChartNetWorkInterface().getLocalIP();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static byte[] getInetAddressByteArray(String ip) {
        String[] ii = ip.split("\\.");
        byte[] ips = new byte[4];
        for (int i = 0; i < 4; i++) {
            ips[i] = (byte) (Integer.parseInt(ii[i]));
        }
        return ips;
    }
}
